POLYT v. 1.0

Generador de Trayectorias y rotaciones para POLYRAY

(c) Miguel Angel Díaz 1.994

El POLYT, es una perqueña tool de ayuda para la generación de archivos fuentes para el POLYRAY raytracer. En sí, genera una serie de ficheros .INC en el que se definen una serie de matrices de trayectorias y de rotaciones. Estos ficheros se incluirán más tarde con la cáusula "include" del POLYRAY.

Este programa es de uso freeware, así que ya sabeis, podeis hacer lo que querais con él, incluso borrarlo.

EL programa está repartido en tres partes, el ejecutable, los ficheros de ejemplo y este documento. Los ficheros que se deben incluir son los siguientes:

POLYT.EXE	Programa ejecutable

POLYT.DOC	Este documento, ASCII.

POLYT.WPD	Este documento, WP6.0

EJ1.PI	Fichero fuente de ejemplo

EJ1.INC	Fichero include de rotaciones

EJ2.INC	Fichero include de traslaciones

EJ3.INC	Fichero include de traslaciones

EJ4.INC	Fichero include de traslaciones

EJ1.FLC	La animación de ejemplo una vez traceada y montada

Tras la ejecución de POLYT lo primero que sale es un pequeño menú:

Para elegir una de las opciones basta con pulsar la tecla deseada. La opción 4 es obvia. La opción 3 no es operativa en esta release.

Antes de ver como funciona la primera opción, relizaremos un pequeño fichero de ejemplo:

Se trata de realizar una animación de 100 fotogramas, en el que se vea una piramide de marmol rojizo girando sobre sí misma durante la mitad del tiempo de la animación, el resto del tiempo se desplaza verticalmente de abajo a arriba y después de arriba a abajo. Todo se efecturá sobre el eje OY. Opcionalmente se pueden incluir algunos objetos y efectos diversos.

El contenido de este ejemplo se encuentra en el fichero EJ1.PI, la definición de la rotación se encuentra en el fichero EJ1.INC, la traslación hacia arriba en EJ2.INC y la traslación hacia abajo en EJ3.INC. En el fichero EJ4.INC se encuentra la traslación de uno de los objetos adicionales. Veamos el ejemplo:

// ---------------------------------- ficheros cabecera generales

include "colors.inc"

include "texture.inc"

// ------------------------- parametros generales de la animacion

// La animacion es de 100 fotogramas comenzando en el fotograma 0 y

// terminando en el fotograma 99. El fichero de salida comenzara por ej1

start_frame 0

end_frame 99

total_frames 100

outfile ej1_

// Podemos distinguir tres intervalos en toda la animacion.

// El primer intervalo es la de la rotacion de la piramide

// El segundo es el del movimiento hacia arriba de la piramide

// El tercero es el del movimiento hacia abajo de la piramide

define intervalo1 50

define intervalo2 75

define intervalo3 100

// ---------------------------------------- parametros de luces y camaras

define tx 640

define ty 480

define pos <-3,0.5,3>

define atpos <0,0.5,0>

viewpoint

{

from pos

at atpos

up <0, 1, 0>

angle 45

resolution tx,ty

aspect 640/480

}

background blue

// ------------------------------------ definicion de texturas

// ---------------------- Textura de la piramide

define piramide_t

texture

{

noise surface

{

color white

position_fn position_objectx

lookup_fn lookup_sawtooth

octaves 3

turbulence 3

ambient 0.3

diffuse 0.8

specular 0.3

microfacet Reitz 5

color_map ([0.0, 0.8, <1, 0.8, 0.8>, <1, 0.4, 0.4>]

[0.8, 1.0, <1, 0.4, 0.4>, <1, 0.1, 0.1>])

}

}

// ---------------------- Textura del suelo

define suelo_t

texture

{

noise surface

{

color white

position_fn position_objectx

lookup_fn lookup_sawtooth

octaves 2

turbulence 8

ambient 0.1

diffuse 0.9

specular 0.5

microfacet Reitz 8

color_map ([0.0, 0.5, <1, 1, 0.8>, <1, 0.4, 0.4>]

[0.5, 1.0, <0.3, 1, 0.4>, <0.2, 0.8, 0.1>])

}

}

// ---------------------- Textura de los ejes

define ejes_t

texture

{

noise surface

{

color white

position_fn position_objectx

lookup_fn lookup_sawtooth

octaves 3

turbulence 3

ambient 0.1

diffuse 0.7

specular white, 0.5

reflection white, 0.1

transmission white, 0.9, 1

microfacet Reitz 5

color_map ([0.0, 0.8, yellow, 0.9, orange, 0.99]

[0.8, 1.0, orange, 0.99, red, 1])

}

}

// ------------------------------------ definicion de los objetos

// --------------------- piramide

define piramide

object

{

object { polygon 4, <0,0,0>, <-1,0,0>, <-1,0,1>, <0,0,1> } +

object { polygon 3, <0,0,0>, <-0.5,1,0.5>, <-1,0,0> } +

object { polygon 3, <0,0,0>, <-0.5,1,0.5>, <0,0,1> } +

object { polygon 3, <0,0,1>, <-0.5,1,0.5>, <-1,0,1> } +

object { polygon 3, <-1,0,1>, <-0.5,1,0.5>, <-1,0,0> }

}

// --------------------- suelo

define suelo

object

{

disc <0,0,0>, <0,1,0>, 100

}

// --------------------- ejes

define ejes

object

{

object { cylinder <0,0,0>, <0,100,0>, 0.05} +

object { cylinder <0,0,0>, <0,0,100>, 0.05} +

object { cylinder <0,0,0>, <100,0,0>, 0.05} +

object { cylinder <0,0,0>, <0,0,-100>, 0.05} +

object { cylinder <0,0,0>, <-100,0,0>, 0.05}

}

// ------------------------------------ Colocacion de los objetos

// ----------------- Objetos fijos

// ----------------- El suelo

suelo

{

suelo_t

translate <0,-0.1,0>

}

// --------------------- ejes

ejes

{

ejes_t

}

// ----------------- Objetos en movimiento

// ----------------- La piramide

if (frame < intervalo1)

{

include "ej1.inc"

piramide

{

piramide_t

translate <0.5,0,-0.5>

rotate <0, piramide_r001[frame], 0>

}

}

else

if ((frame >= intervalo1) && (frame < intervalo2))

{

include "ej2.inc"

piramide

{

piramide_t

translate piramide_t001[frame - intervalo1]

}

}

else

if ((frame >= intervalo2) && (frame < intervalo3))

{

include "ej3.inc"

piramide

{

piramide_t

translate piramide_t002[frame - intervalo2]

}

}

// ----------------- La luz

include "ej4.inc"

light luz_t001[frame]

Observando el enunciado del problema y el código fuente distinguimos tres partes separadas de la animación, definidas por los valores de los intervalos. En el primer intervalo lo que debemos es girar la piramide sobre si misma y sobre el eje OY. Dicho intervalo dura 50 fotogramas.

Para obtener la matriz con los distintos valores de la rotación llamamos al programa Polyt tal como se mencionó anteriormente. Una vez estemos en el menú principal deberemos seleccionar la opción 1.

A continuación el programa nos pide el número máximo de fotogramas, es decir,de los distintos valores de giro (en grados) que se almacenarán en la matriz de rotacones. El máximo fijado es de 1024 fotogramas. En nuestro caso de ejemplo teclearemos 50 seguido de INTRO.

En este punto se nos pedirá que introduzcamos el ángulo inicial y final de la rotación, es decir, el arco que queremos barrer. En este caso como queremos realizar un giro completo introduciremos como valor incial 0 y como valor final 360. Tenemos que tener en cuenta dos cosas. La primera es que ambos ángulos deben ser siempre positivos. No introducir nunca valores negativos, ya que en este caso el programa no generará el código adecuadamente. El angulo final puede ser de un valor inferior al del angulo incial. En segundo lugar si introducimos ángulos de tres dígitos no es necesario que pulsemos la tecla INTRO. El programa lo detectará automáticamente.

Despues de esto el programa nos pedirá el sentido de giro. Horario (+) o antihorario (-). Basta con pulsar uno de los valores sin pulsar INTRO. En nuestro ejemplo pulsaremos la tecla +.

El siguiente paso es introducir el nombre de fichero sin extensión. Si la longitud que tecleamos es inferior a 8 caracteres deberemos pulsar INTRO cuando terminemos. En caso contrario el programa detectará automáticamente que hemos introducido los ocho dígitos.

Una vez introducido el nombre que deseamos para el fichero (en nuetro caso de ejemplo teclearemos ej1), el programa nos mostrará el nombre completo (\ej1.inc) y nos solicitará que pulsemos 'S' para continuar o 'n' para corregir el nombre en caso erroneo.

Deberemos tener en cuenta que el fichero se graba por defecto siempre en el directorio raiz de la unidad activa.

Una vez que estemos de acuerdo. El programa nos solicitará el nombre de la matriz que debe colocar como etiqueta en la orden define de Polyray. Podremos usar un valor de hasta 25 caracteres. (Teclear para el ejemplo piramide_r001). Una vez introducida nos preguntará si estamos de acuerdo con el nombre. En caso afirmativo calculará los valores de giro a partir de los parámetros, nos los mostrará por pantalla y los grabará en disco, retornando al menú principal una vez pulsemos una tecla.

El contenido del fichero generado para nuestro ejemplo (ej1.inc) es:

// ------------------------- Matriz de rotaciones

define piramide_r001

[ 000.000, 007.200, 014.400, 021.600, 028.800,

036.000, 043.200, 050.400, 057.600, 064.800,

072.000, 079.200, 086.400, 093.600, 100.800,

108.000, 115.200, 122.400, 129.600, 136.800,

144.000, 151.200, 158.400, 165.600, 172.800,

180.000, 187.200, 194.400, 201.600, 208.800,

216.000, 223.200, 230.400, 237.600, 244.800,

252.000, 259.200, 266.400, 273.600, 280.800,

288.000, 295.200, 302.400, 309.600, 316.800,

324.000, 331.200, 338.400, 345.600, 352.800]

Continuando con el ejemplo, lo que debemos realizar ahora es calcular el desplazamiento vertizal hacia arriba. Para ello elegimos la opción 2 del menú principal.

En este caso igual que el anterior nos pide el número de fotogramas (número de valores a generar). Introduciremos 25 (nos quedaban 50 fotogramas, 25 los usaremos para el movimiento hacia arriba y el resto para el desplazamiento hacia abajo) y pulsamos INTRO.

Nos pide a continuación por un lado el nombre del fichero y por otro el nombre de la matriz. Deberemos operar igual que en ejemplo anterior. Introduciremos en este caso "ej2". Como nombre de matriz usaremos piramide_t001.

Finalizados estos pasos se nos pedirán las a coordenadas del punto inicial y final. Introducir los valores 0.5, 0, -0.5, para el valor inicial y 0.5, 1, -0.5 para el punto final. Podemos observar en este caso que podemos usar numeros reales con o sin signo.

El contenido del fichero ej2.inc es el siguiente:

//---------------- Matriz de posiciones

define piramide_t001[

<0.500, 0.000, -0.500>, <0.500, 0.040, -0.500>, <0.500, 0.080, -0.500>,

<0.500, 0.120, -0.500>, <0.500, 0.160, -0.500>, <0.500, 0.200, -0.500>,

<0.500, 0.240, -0.500>, <0.500, 0.280, -0.500>, <0.500, 0.320, -0.500>,

<0.500, 0.360, -0.500>, <0.500, 0.400, -0.500>, <0.500, 0.440, -0.500>,

<0.500, 0.480, -0.500>, <0.500, 0.520, -0.500>, <0.500, 0.560, -0.500>,

<0.500, 0.600, -0.500>, <0.500, 0.640, -0.500>, <0.500, 0.680, -0.500>,

<0.500, 0.720, -0.500>, <0.500, 0.760, -0.500>, <0.500, 0.800, -0.500>,

<0.500, 0.840, -0.500>, <0.500, 0.880, -0.500>, <0.500, 0.920, -0.500>,

<0.500, 0.960, -0.500>, <0.500, 1.000, -0.500>]

Para obtener la matriz del desplazamiento hacia abajo deberemos seguir los mismos pasos que en éste último caso. El contenido del fichero generado (ej3.inc) es el siguiente:

//---------------- Matriz de posiciones

define piramide_t002[

<0.500, 1.000, -0.500>, <0.500, 0.960, -0.500>, <0.500, 0.920, -0.500>,

<0.500, 0.880, -0.500>, <0.500, 0.840, -0.500>, <0.500, 0.800, -0.500>,

<0.500, 0.760, -0.500>, <0.500, 0.720, -0.500>, <0.500, 0.680, -0.500>,

<0.500, 0.640, -0.500>, <0.500, 0.600, -0.500>, <0.500, 0.560, -0.500>,

<0.500, 0.520, -0.500>, <0.500, 0.480, -0.500>, <0.500, 0.440, -0.500>,

<0.500, 0.400, -0.500>, <0.500, 0.360, -0.500>, <0.500, 0.320, -0.500>,

<0.500, 0.280, -0.500>, <0.500, 0.240, -0.500>, <0.500, 0.200, -0.500>,

<0.500, 0.160, -0.500>, <0.500, 0.120, -0.500>, <0.500, 0.080, -0.500>,

<0.500, 0.040, -0.500>, <0.500, 0.000, -0.500>]

Para terminar se ha añadido un pequeño efecto especial. Desplazaremos una luz a lo largo de toda la animación para ver el efecto que ésta produce en el paisaje y el desplazamiento de la sombra de la piramide.

Deberemos obrar igual que en los casos anterior, salvo que, como se debe desplazar a lo largo de toda la animación, deberemos introducir 100 cuando nos pidan el valor de los fotogramas. Su definición se salvará en el fichero ej4.inc, cuyo contenido es el siguiente:

//---------------- Matriz de posiciones

define luz_t001[

<-10.000, 3.000, 10.000>, <-10.000, 3.000, 9.800>, <-10.000, 3.000, 9.600>,

<-10.000, 3.000, 9.400>, <-10.000, 3.000, 9.200>, <-10.000, 3.000, 9.000>,

<-10.000, 3.000, 8.800>, <-10.000, 3.000, 8.600>, <-10.000, 3.000, 8.400>,

<-10.000, 3.000, 8.200>, <-10.000, 3.000, 8.000>, <-10.000, 3.000, 7.800>,

<-10.000, 3.000, 7.600>, <-10.000, 3.000, 7.400>, <-10.000, 3.000, 7.200>,

<-10.000, 3.000, 7.000>, <-10.000, 3.000, 6.800>, <-10.000, 3.000, 6.600>,

<-10.000, 3.000, 6.400>, <-10.000, 3.000, 6.200>, <-10.000, 3.000, 6.000>,

<-10.000, 3.000, 5.800>, <-10.000, 3.000, 5.600>, <-10.000, 3.000, 5.400>,

<-10.000, 3.000, 5.200>, <-10.000, 3.000, 5.000>, <-10.000, 3.000, 4.800>,

<-10.000, 3.000, 4.600>, <-10.000, 3.000, 4.400>, <-10.000, 3.000, 4.200>,

<-10.000, 3.000, 4.000>, <-10.000, 3.000, 3.800>, <-10.000, 3.000, 3.600>,

<-10.000, 3.000, 3.400>, <-10.000, 3.000, 3.200>, <-10.000, 3.000, 3.000>,

<-10.000, 3.000, 2.800>, <-10.000, 3.000, 2.600>, <-10.000, 3.000, 2.400>,

<-10.000, 3.000, 2.200>, <-10.000, 3.000, 2.000>, <-10.000, 3.000, 1.800>,

<-10.000, 3.000, 1.600>, <-10.000, 3.000, 1.400>, <-10.000, 3.000, 1.200>,

<-10.000, 3.000, 1.000>, <-10.000, 3.000, 0.800>, <-10.000, 3.000, 0.600>,

<-10.000, 3.000, 0.400>, <-10.000, 3.000, 0.200>, <-10.000, 3.000, 0.000>,

<-10.000, 3.000, -0.200>, <-10.000, 3.000, -0.400>, <-10.000, 3.000, -0.600>,

<-10.000, 3.000, -0.800>, <-10.000, 3.000, -1.000>, <-10.000, 3.000, -1.200>,

<-10.000, 3.000, -1.400>, <-10.000, 3.000, -1.600>, <-10.000, 3.000, -1.800>,

<-10.000, 3.000, -2.000>, <-10.000, 3.000, -2.200>, <-10.000, 3.000, -2.400>,

<-10.000, 3.000, -2.600>, <-10.000, 3.000, -2.800>, <-10.000, 3.000, -3.000>,

<-10.000, 3.000, -3.200>, <-10.000, 3.000, -3.400>, <-10.000, 3.000, -3.600>,

<-10.000, 3.000, -3.800>, <-10.000, 3.000, -4.000>, <-10.000, 3.000, -4.200>,

<-10.000, 3.000, -4.400>, <-10.000, 3.000, -4.600>, <-10.000, 3.000, -4.800>,

<-10.000, 3.000, -5.000>, <-10.000, 3.000, -5.200>, <-10.000, 3.000, -5.400>,

<-10.000, 3.000, -5.600>, <-10.000, 3.000, -5.800>, <-10.000, 3.000, -6.000>,

<-10.000, 3.000, -6.200>, <-10.000, 3.000, -6.400>, <-10.000, 3.000, -6.600>,

<-10.000, 3.000, -6.800>, <-10.000, 3.000, -7.000>, <-10.000, 3.000, -7.200>,

<-10.000, 3.000, -7.400>, <-10.000, 3.000, -7.600>, <-10.000, 3.000, -7.800>,

<-10.000, 3.000, -8.000>, <-10.000, 3.000, -8.200>, <-10.000, 3.000, -8.400>,

<-10.000, 3.000, -8.600>, <-10.000, 3.000, -8.800>, <-10.000, 3.000, -9.000>,

<-10.000, 3.000, -9.200>, <-10.000, 3.000, -9.400>, <-10.000, 3.000, -9.600>,

<-10.000, 3.000, -9.800>, <-10.000, 3.000, -10.000>]

Como podemos ver el manejo del programa es muy sencillo. Las principales ventajas de usar matrices para generar los desplazamientos son:

- Evitamos el uso de las ecuaciones, que por lo general dificultan la lectura del código fuente.

- Ahorramos algo de tiempo al liberar a Polyray de extensos cálculos matemáticos.

- Es más fácil ver la trayectoria de un objeto ya que tenemos todas las coordenadas que va a seguir.

- En el caso de que una animación se quede a medio generar por alguna causa externa imprevista. Podemos continuar sin ningún tipo de problema justo por el sitio donde se quedó. Basta con editar el fichero .PI y colocar en la cláusula start_frame el número del fotogrma en el que se produjo el error.

Como desventajas tenemos:

- La inmensa cantidad de código que se genera.

- El tener que definir todos los puntos en el caso de que modifiquemos algún parámetro, como pueden ser los puntos inicial y final de la animación - las ecuaciones se ajustan automáticamente.